(function(angular) {
	'use strict';
	angular.module('fs.waf').factory('productService', productService);
	productService.$inject = [ '$q', '$timeout', 'loggerFactory', 'commonService', 'ajaxServiceFactory', 'modalService', 'gridService', 'arithService', 'profFilterOptionService' ];
	function productService($q, $timeout, loggerFactory, commonService, ajaxServiceFactory, modalService, gridService, arithService, profFilterOptionService) {
		var log = loggerFactory.getLogger("productService"), ajaxService = ajaxServiceFactory.buildAjaxService({
			getProdSubtypeOptions : {
				url : 'do/cda/dataList/prodSubtypeOptions',
				method : 'get'
			},
			getProductOptions : {
				url : 'do/cda/dataList/productOptions',
				method : 'get'
			},
			getLayoutConfigByProdType: {
				url : 'do/cda/product/layout',
				method : 'post'					
			},
		});
		
		function initGeneral($scope, ctrl, updateProcessFlag) {
			var defer = $q.defer();
			profFilterOptionService.initProfFilterOptions(ctrl).then(function() {
				getProductOptions().then(function(response) {
					ctrl.prodSubtypeOptions = response.prodSubtypeOptions;
					ctrl.loanAmtRangeCcyOptions = response.currenciesOptions;
					ctrl.yesNoOptions = response.yesNoOptions;
					ctrl.payPriorityOptions = response.payPriorityOptions;
					ctrl.fundsrcCodeOptions = response.fundsrcCodeOptions;
					ctrl.billFreqTypeOptions = response.billFreqTypeOptions;
					ctrl.intCatOptions = response.intCatOptions;// multi interest
					ctrl.facilityCatOptions = response.facilityCatOptions;// multi limit facility category
					defer.resolve();
				}, angular.noop);
			});
			
			ctrl.prodSubtypeChanged = function(value) {
				if (ctrl.product.prodSubtype && ctrl.product.prodSubtype != ctrl.product.oldProdSubtype) {
					ctrl.product.oldProdSubtype = ctrl.product.prodSubtype;
					for (var i = 0; i < ctrl.prodSubtypeOptions.length; i++) {
						var _prodSubtype = ctrl.prodSubtypeOptions[i];
						if (_prodSubtype.value == ctrl.product.prodSubtype) {
							resetProdByProdSubtypeExtProperty(ctrl, _prodSubtype);
							// only change need reset, because of model has also addPrincFlag value
							// show or not by prodSubtypeExtProperty.upAddPrinc, and value copy from addPrincFlag
							ctrl.product.addPrincFlag = ctrl.product.prodSubtypeExtProperty.addPrincFlag;
							// create wf prodsubType can change
							changeLayoutConfig($scope, ctrl, ctrl.action);
							break;
						}
					}
				}
			};
			
			return defer.promise;
		}
		function getProductOptions() {
			var defer = $q.defer();
			ajaxService.getProductOptions().then(function(response) {
				var productOptions = {};
				if (response.data) {
					angular.forEach(response.data, function(value, key) {
						var tempValue = {};
						tempValue = value;
						productOptions[key] = tempValue;
					});
				}
				defer.resolve(productOptions);
			});
			return defer.promise;
		}
		
		function initLayoutConfigAndModel ($scope, ctrl, initProduct, action, updateProcessFlag) {
			var defer3 = $q.defer();
			if (initProduct.prodSubtype) {
				initProduct.oldProdSubtype = initProduct.prodSubtype;
				for (var i = 0; i < ctrl.prodSubtypeOptions.length; i++) {
					var _prodSubtype = ctrl.prodSubtypeOptions[i];
					if (_prodSubtype.value == initProduct.prodSubtype) {
						resetProdByProdSubtypeExtProperty(ctrl, _prodSubtype, initProduct);
						break;
					}
				}
				//
				var params = {};
				params.action = action;
				params.prodSubtype = initProduct.prodSubtypeExtProperty.prodSubtypeName;
				params.prodType = initProduct.prodSubtypeExtProperty.prodType;
				ajaxService.getLayoutConfigByProdType(params).then(function(response) {
					// $attrs.fsValidatorConfig change , then can update new $scope._fsValidatorConfig
					resetValidateByProdSubtype($scope, ctrl, initProduct);
					// 1. change layout
					var newLayoutConfig = addLayoutConfigForMulti(ctrl, response.data);
					initMultiTableDefine(newLayoutConfig, $scope, ctrl, updateProcessFlag);
					ctrl.layoutConfig = newLayoutConfig;
					$timeout(function() {
						// reset model after change layout
						resetDataModel(ctrl, initProduct);
						ctrl.product = initProduct;
						defer3.resolve();
					});
				});
			}
			// create also get layout again for get all dynaparm by product
			// this will get '*'
			else if (action == 'create') {
				var params = {};
				params.action = action;
				params.prodSubtype = '';
				params.prodType = '';
				ajaxService.getLayoutConfigByProdType(params).then(function(response) {
					// $attrs.fsValidatorConfig change , then can update new $scope._fsValidatorConfig
					resetValidateByProdSubtype($scope, ctrl, initProduct);
					// 1. change layout
					var newLayoutConfig = addLayoutConfigForMulti(ctrl, response.data);
					initMultiTableDefine(newLayoutConfig, $scope, ctrl, updateProcessFlag);
					ctrl.layoutConfig = newLayoutConfig;
					// reset model after change layout
					$timeout(function(){
						resetDataModel(ctrl, initProduct);
						ctrl.product = initProduct;
						defer3.resolve();
					});
				});
			}
			return defer3.promise;
		};
		
		function changeLayoutConfig ($scope, ctrl, action) {
			// $attrs.fsGridConfig change then can invoke prepareGridRules, it's used by ctrl.changeLayoutConfig, for trigger for add required or not
			ctrl.layoutConfig.formConfigs.profBilling = {};
			if (ctrl.product.prodSubtype) {
				var params = {};
				params.action = action;
				params.prodSubtype = ctrl.product.prodSubtypeExtProperty.prodSubtypeName;
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				ajaxService.getLayoutConfigByProdType(params).then(function(response) {
					var tmp = angular.copy(ctrl.product);
					// $attrs.fsValidatorConfig change , then can update new $scope._fsValidatorConfig
					resetValidateByProdSubtype($scope, ctrl);
					// 1. change layout
					// 2. $attrs.fsGridConfig change then also can invoke prepareGridRules, trigger for add required or not
					ctrl.layoutConfig = addLayoutConfigForMulti(ctrl, response.data);
					// reset model after change layout
					$timeout(function(){
						ctrl.product = tmp;
					});
					
				});
			} 
		};
		
		function addLayoutConfigForMulti(ctrl, resLayoutConfig) {
			if (!resLayoutConfig) return resLayoutConfig;
			/**
			   "profInt": {
					"name": "profInt",
					"tableConfigs": {
						"table": {
							"name": "table",
							"enableOperation": true,
							"enableOperationRemoveSelected": true,
							"addRow": "vm.addProfInt",
							"editRow": "vm.editProfInt",
							"removeSelectedRows": "vm.removeProfInt",
							"columnDefs": [...]
						}
					}
				},
			 */
			var profIntLayoutTemplate = resLayoutConfig.formConfigs.profInt;
			if (ctrl.intCatOptions && ctrl.intCatOptions.length > 0) {
				for (var i = 0; i < ctrl.intCatOptions.length; i++) {
					var intCat = ctrl.intCatOptions[i].value;
					var layoutTmp = angular.copy(profIntLayoutTemplate);
					layoutTmp.name = 'profInt' + intCat;
					if (layoutTmp.tableConfigs.table.addRow)
						layoutTmp.tableConfigs.table.addRow = layoutTmp.tableConfigs.table.addRow + '.' + intCat;
					if (layoutTmp.tableConfigs.table.editRow)
						layoutTmp.tableConfigs.table.editRow = layoutTmp.tableConfigs.table.editRow + '.' + intCat;
					if (layoutTmp.tableConfigs.table.removeSelectedRows)
						layoutTmp.tableConfigs.table.removeSelectedRows = layoutTmp.tableConfigs.table.removeSelectedRows + '.' + intCat;
					if (layoutTmp.tableConfigs.table.viewRow)
						layoutTmp.tableConfigs.table.viewRow = layoutTmp.tableConfigs.table.viewRow + '.' + intCat;
					resLayoutConfig.formConfigs['profInt' + intCat] = layoutTmp;
				}
			}
			/**
			   "profLimitFaci": {
					"name": "profLimitFaci",
					"tableConfigs": {
						"table": {
							"name": "table",
							"enableOperation": true,
							"enableOperationRemoveSelected": true,
							"addRow": "vm.addProfLimitFaci",
							"editRow": "vm.editProfLimitFaci",
							"removeSelectedRows": "vm.removeProfLimitFaci",
							"columnDefs": [...]
						}
					}
				},
			 */
			var profLimitFaciLayoutTemplate = resLayoutConfig.formConfigs.profLimitFaci;
			if (ctrl.facilityCatOptions && ctrl.facilityCatOptions.length > 0) {
				for (var i = 0; i < ctrl.facilityCatOptions.length; i++) {
					var facilityCat = ctrl.facilityCatOptions[i].value;
					var layoutTmp = angular.copy(profLimitFaciLayoutTemplate);
					layoutTmp.name = 'profLimitFaci' + facilityCat;
					if (layoutTmp.tableConfigs.table.addRow)
						layoutTmp.tableConfigs.table.addRow = layoutTmp.tableConfigs.table.addRow + '.' + facilityCat;
					if (layoutTmp.tableConfigs.table.editRow)
						layoutTmp.tableConfigs.table.editRow = layoutTmp.tableConfigs.table.editRow + '.' + facilityCat;
					if (layoutTmp.tableConfigs.table.removeSelectedRows)
						layoutTmp.tableConfigs.table.removeSelectedRows = layoutTmp.tableConfigs.table.removeSelectedRows + '.' + facilityCat;
					if (layoutTmp.tableConfigs.table.viewRow)
						layoutTmp.tableConfigs.table.viewRow = layoutTmp.tableConfigs.table.viewRow + '.' + facilityCat;
					resLayoutConfig.formConfigs['profLimitFaci' + facilityCat] = layoutTmp;
				}
			}
			return resLayoutConfig;
		}
		
		function initMultiTableDefine(newLayoutConfig, $scope, ctrl, updateProcessFlag) {
			initMultiProfInt(newLayoutConfig, $scope, ctrl, updateProcessFlag);
			initMultiProfLimitFaci(newLayoutConfig, $scope, ctrl, updateProcessFlag);
		}
		
		/**
		 * build productTmp profInts
		 */
		function resetDataModel(ctrl, initProduct) {
			var initProductTmp = {};
			if (ctrl.intCatOptions && ctrl.intCatOptions.length > 0) {
				for (var i = 0; i < ctrl.intCatOptions.length; i++) {
					var intCat = ctrl.intCatOptions[i].value;
					var belongIntCatProfInts = [];
					if (initProduct.profInts && initProduct.profInts.length > 0) {
						for (var j = 0; j < initProduct.profInts.length; j++) {
							if (initProduct.profInts[j].intCat == intCat) {
								belongIntCatProfInts.push(initProduct.profInts[j]);
							}
						}
					}
					initProductTmp['profInts' + intCat] = belongIntCatProfInts;
				}
			}
			if (ctrl.facilityCatOptions && ctrl.facilityCatOptions.length > 0) {
				for (var i = 0; i < ctrl.facilityCatOptions.length; i++) {
					var facilityCat = ctrl.facilityCatOptions[i].value;
					var belongFacilityCatProfLimitFacis = [];
					if (initProduct.profLimitFacis && initProduct.profLimitFacis.length > 0) {
						for (var j = 0; j < initProduct.profLimitFacis.length; j++) {
							if (initProduct.profLimitFacis[j].facilityCat == facilityCat) {
								belongFacilityCatProfLimitFacis.push(initProduct.profLimitFacis[j]);
							}
						}
					}
					initProductTmp['profLimitFacis' + facilityCat] = belongFacilityCatProfLimitFacis;
				}
			}
			ctrl.productTmp =  initProductTmp;
			
			if (ctrl.productOld && ctrl.productOld.profInts) {
				var initProductOldTmp = {};
				if (ctrl.intCatOptions && ctrl.intCatOptions.length > 0) {
					for (var i = 0; i < ctrl.intCatOptions.length; i++) {
						var intCat = ctrl.intCatOptions[i].value;
						var belongIntCatProfInts = [];
						if (ctrl.productOld.profInts && ctrl.productOld.profInts.length > 0) {
							for (var j = 0; j < ctrl.productOld.profInts.length; j++) {
								if (ctrl.productOld.profInts[j].intCat == intCat) {
									belongIntCatProfInts.push(ctrl.productOld.profInts[j]);
								}
							}
						}
						initProductOldTmp['profInts' + intCat] = belongIntCatProfInts;
					}
				}
				if (ctrl.facilityCatOptions && ctrl.facilityCatOptions.length > 0) {
					for (var i = 0; i < ctrl.facilityCatOptions.length; i++) {
						var facilityCat = ctrl.facilityCatOptions[i].value;
						var belongFacilityCatProfLimitFacis = [];
						if (ctrl.productOld.profLimitFacis && ctrl.productOld.profLimitFacis.length > 0) {
							for (var j = 0; j < ctrl.productOld.profLimitFacis.length; j++) {
								if (ctrl.productOld.profLimitFacis[j].facilityCat == facilityCat) {
									belongFacilityCatProfLimitFacis.push(ctrl.productOld.profLimitFacis[j]);
								}
							}
						}
						initProductOldTmp['profLimitFacis' + facilityCat] = belongFacilityCatProfLimitFacis;
					}
				}
				ctrl.productOldTmp =  initProductOldTmp;
			}
		}
		
		/**
		 * reset validate
		 * in edit page some tabs(no popup) hidden, those tabs js validation need clear
		 * 
		 */
		function resetValidateByProdSubtype($scope, ctrl, initProduct) {
			if (ctrl.initValidatorConfig) {
				var tmpProduct;
				if (initProduct) {
					tmpProduct = initProduct;
				} else {
					tmpProduct = ctrl.product;
				}
				
				ctrl.tmpValidatorConfig = angular.copy(ctrl.initValidatorConfig);
				if (tmpProduct.prodSubtypeExtProperty) {
					if (!(tmpProduct.prodSubtypeExtProperty.upBilling == 'Y')) {
						ctrl.tmpValidatorConfig.profBilling = {};
					}
					if (!(tmpProduct.prodSubtypeExtProperty.upChargeback == 'Y')) {
						ctrl.tmpValidatorConfig.profChargeback = {};
					}
					if (!(tmpProduct.prodSubtypeExtProperty.upPayschd == 'Y')) {
						ctrl.tmpValidatorConfig.profPayschd = {};
					}
					if (!(tmpProduct.prodSubtypeExtProperty.upInvfilter == 'Y')) {
						ctrl.tmpValidatorConfig.profInvfilter = {};
					}
					
				}
				ctrl.validatorConfig = ctrl.tmpValidatorConfig;
			}
		}
		
		function resetProdByProdSubtypeExtProperty (ctrl , _prodSubtype, initProduct) {
			var tmpProduct;
			if (initProduct) {
				tmpProduct = initProduct;
			} else {
				tmpProduct = ctrl.product;
			}
			tmpProduct.prodSubtypeExtProperty = _prodSubtype.extProperty;
			
			// readonly, and value from _prodSubtype
			tmpProduct.directIssueFlag = tmpProduct.prodSubtypeExtProperty.directIssueFlag;
			tmpProduct.intOnlyFlag = tmpProduct.prodSubtypeExtProperty.intOnlyFlag;
			tmpProduct.amdFlag = tmpProduct.prodSubtypeExtProperty.amdFlag;
			//
			/**
			 * Y/N, whether enable partial pay setting on product level. 
			 * If it is Y, then on product level Allow Partial Pay is configurable; 
			 * if it is N, then partial pay is not allowed and can not be configured on product level.
			 */
			if (tmpProduct.prodSubtypeExtProperty.upPartialPay != 'Y') {
				tmpProduct.partialPayFlag = 'N';
			}
			/**
			 * Y/N, whether enable early payoff setting on product level. 
			 * If it is Y, then on product level Allow Early Payoff is configurable; 
			 * if it is N, then early payoff is not allowed and it cannot be configured on product level.
			 */
			if (tmpProduct.prodSubtypeExtProperty.upEarlyPayoff != 'Y') {
				tmpProduct.earlyPayoffFlag = 'N';
			}
			/**
			 * Y/N, whether enable amend principal setting on product level. 
			 * If it is Y, then on product level Add Principal is configurable; 
			 * if it is N, then Add Principal is not allowed and it can not be configured on product level.
			 */
			if (tmpProduct.prodSubtypeExtProperty.upAddPrinc != 'Y') {
				tmpProduct.addPrincFlag = 'N';
			}
			
			/**
			 * '*' means for all categories. Null means no category.  
			 * NF means for normal interest and cost-of-fund interest categories.
			 */
			var filterUpIntCats = tmpProduct.prodSubtypeExtProperty.upIntCats;
			tmpProduct.interestCatShowFlag = {};
			angular.forEach(ctrl.intCatOptions, function(intCatOption) {
				var intCat = intCatOption.value;
				if (!filterUpIntCats) {
					tmpProduct.interestCatShowFlag[intCat] = 'N';
				} else {
					if (filterUpIntCats == '*' || filterUpIntCats.indexOf(intCat) >= 0) {
						tmpProduct.interestCatShowFlag[intCat] = 'Y';
					} else {
						tmpProduct.interestCatShowFlag[intCat] = 'N';
					}
				}
			});	
			
			/**
			 * '*' means for all categories. Null means no category.  
			 * CI means for Credit and Insurance facility categories.
			 */
			var filterUpFacilityCats = tmpProduct.prodSubtypeExtProperty.upFacilityCats;
			tmpProduct.facilityCatShowFlag = {};
			angular.forEach(ctrl.facilityCatOptions, function(facilityCatOption) {
				var facilityCat = facilityCatOption.value;
				if (!filterUpFacilityCats) {
					tmpProduct.facilityCatShowFlag[facilityCat] = 'N';
				} else {
					if (filterUpFacilityCats == '*' || filterUpFacilityCats.indexOf(facilityCat) >= 0) {
						tmpProduct.facilityCatShowFlag[facilityCat] = 'Y';
					} else {
						tmpProduct.facilityCatShowFlag[facilityCat] = 'N';
					}
				}
			});
			
			// set aome default such as profBilling profChargeback profPayschd profInvfilter
			if (tmpProduct.dataStatus && tmpProduct.prodSubtypeExtProperty.upBilling == 'Y') {
				if (!tmpProduct.profBilling)
					tmpProduct.profBilling = {};
				if (!tmpProduct.profBilling.billFreqType)
					tmpProduct.profBilling.billFreqType = 'N';
				if (!tmpProduct.profBilling.billOnEomFlag)
					tmpProduct.profBilling.billOnEomFlag = 'N';
			}
		}
		
		function initProfAcct(initLayoutConfig, $scope, ctrl, updateProcessFlag) {
			//init profAcct grid
			ctrl.profAcctInnerGridOptions = gridService.createInnerGridOptions($scope, initLayoutConfig.formConfigs.profAcct.tableConfigs.table, profAcctRowSelectionChanged);
			ctrl.profAcctInnerGridOptions.data = 'vm.product.profAccts';
			ctrl.profAcctInnerGridOptions.verifyData = 'vm.productOld.profAccts';
			// if view page, delete table checkbox
			if (!ctrl.profAcctInnerGridOptions.enableOperationRemoveSelected) {
				ctrl.profAcctInnerGridOptions.enableRowHeaderSelection = false;
			}
			function profAcctRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedProfAccts = selectedRows;
			}
			
			ctrl.addProfAcct = function(currRow) {
				return $q(function(resolved, rejected){
					// params
					var params = {};
					params.filterEventCodes = [];
					angular.forEach(ctrl.product.profAccts, function(profAcct, index) {
						params.filterEventCodes.push(profAcct.eventCode);
					});
					params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
					modalService.openCustomDialogs({
					   'title': 'Account Info',
					   'dialogsModule' : 'cda.profacct.popupedit',
					   'params': params,
					   'btnCallback' : {
						   'ok' : function(profAcct) {							
							   angular.merge(currRow, profAcct);
							   resolved();
							}
						}
					});	
				});
			};
			
			ctrl.editProfAcct = function(currRow) {
				var params = {};
				// for show selected service on popup page
				var _selectedProfAcct = currRow.entity;
				params.profAcct = angular.copy(_selectedProfAcct);
				params.filterEventCodes = [];
				angular.forEach(ctrl.product.profAccts, function(profAcct, index) {
					params.filterEventCodes.push(profAcct.eventCode);
				});
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				params.updateProcessFlag  = updateProcessFlag;
				params.isEdit = 'Y';
				modalService.openCustomDialogs({
					   'title': 'Account Info',
					   'dialogsModule' : 'cda.profacct.popupedit',
					   'params': params,
					   'btnCallback' : {
							'ok' : function(profAcct) {							
								if (!(profAcct.dataStatus == 'C' || profAcct.dataStatus == 'U')) {
									if (updateProcessFlag) {
										profAcct.dataStatus = 'U';
									} else {
										profAcct.dataStatus = 'C';
									}
								}
								angular.extend(_selectedProfAcct, profAcct);
							}
						}		
				});			
			};
			
			ctrl.viewProfAcct = function(currRow) {		
				var params = {};
				// for show selected service on popup page
				var _selectedProfAcct = currRow.entity;
				params.profAcct = angular.copy(_selectedProfAcct);
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				//
				if (ctrl.productOld && ctrl.productOld.profAccts) {
					var oldModel4SelectedRow;
					angular.forEach(ctrl.productOld.profAccts, function(profAcct, index) {
						if (profAcct.eventCode == params.profAcct.eventCode) {
							oldModel4SelectedRow = profAcct;
						}
					});
					params.profAcctOld = oldModel4SelectedRow;
				}
				modalService.openCustomDialogs({
				   'title': 'Account Info',
				   'dialogsModule' : 'cda.profacct.popupview',
				   'params':params,
				   'btnCallback' : {
						'ok' : function(profAcct) {						
						}
					}		
				});
			};
			
		};
		
		function initMultiProfInt(initLayoutConfig, $scope, ctrl, updateProcessFlag) {
			if(ctrl.intCatOptions){
				ctrl.profIntCats = angular.copy(ctrl.intCatOptions);// for page ng-repeat
				ctrl.profIntMultiInnerGridOptions = {};
				ctrl.selectedProfInts = {};
				ctrl.addProfInt = {};
				ctrl.editProfInt = {};
				ctrl.viewProfInt = {};
				ctrl.removeProfInt = {};
				angular.forEach(ctrl.intCatOptions, function(intCatOption) {
					var intCat = intCatOption.value;
					
					//init profCostOfFundInt grid
					var profIntLayoutName = 'profInt' + intCat;
					var profIntRowSelectionChanged = {};
					profIntRowSelectionChanged[intCat] = function(eventRow, selectedRows) {
						ctrl.selectedProfInts[intCat] = selectedRows;
					}
					ctrl.profIntMultiInnerGridOptions[intCat] = gridService.createInnerGridOptions($scope, initLayoutConfig.formConfigs[profIntLayoutName].tableConfigs.table, profIntRowSelectionChanged[intCat]);
					ctrl.profIntMultiInnerGridOptions[intCat].data = 'vm.productTmp.profInts' + intCat;
					ctrl.profIntMultiInnerGridOptions[intCat].verifyData = 'vm.productOldTmp.profInts' + intCat;
					// if view page, delete table checkbox
					if (!ctrl.profIntMultiInnerGridOptions[intCat].enableOperationRemoveSelected) {
						ctrl.profIntMultiInnerGridOptions[intCat].enableRowHeaderSelection = false;
					}
					
					ctrl.addProfInt[intCat] = function(currRow) {
						return $q(function(resolved, rejected){
							// params
							var params = {};
							params.filterPrimaryKeys = [];
							angular.forEach(ctrl.productTmp['profInts' + intCat], function(profInt, index) {
								params.filterPrimaryKeys.push(profInt.ccy + ":" + profInt.intCat);
							});
							params.profInt = {};
							params.profInt.intCat = intCat;
							params.profInt.intSpreadType = 'F';
							// prodSubtypeExtProperty
							params.prodSubtypeExtProperty = ctrl.product.prodSubtypeExtProperty;
							// cda.profint.popupedit receive obj is profInt
							params.isAdd = 'Y';
							modalService.openCustomDialogs({
							   'title': ' Interest Info',
							   'dialogsModule' : 'cda.profint.popupedit',
							   'size' : [1100,500],
							   'params': params,
							   'btnCallback' : {
								   'ok' : function(profInt) {
									   // only add ctrl.product.profIntTmpsx
									   angular.merge(currRow, profInt);
									   // also need add in ctrl.product.profInts for submit service
									   if (!ctrl.product.profInts) ctrl.product.profInts = [];
									   ctrl.product.profInts.push(currRow);
									   resolved();
									}
								}		
							});	
					   });
					};
					
					ctrl.editProfInt[intCat] = function(currRow) {
						var params = {};
						// for show selected service on popup page
						var _selectedProfInt = currRow.entity;
						params.profInt = angular.copy(_selectedProfInt);
						params.filterPrimaryKeys = [];
						angular.forEach(ctrl.productTmp['profInts' + intCat], function(profInt, index) {
							params.filterPrimaryKeys.push(profInt.ccy + ":" + profInt.intCat);
						});
						params.isEdit = 'Y';
						// prodSubtypeExtProperty
						params.prodSubtypeExtProperty = ctrl.product.prodSubtypeExtProperty;
						modalService.openCustomDialogs({
							   'title': ' Interest Info',
							   'dialogsModule' : 'cda.profint.popupedit',
							   'size' : [1100,500],
							   'params': params,
							   'btnCallback' : {
									'ok' : function(profInt) {							
										if (!(profInt.dataStatus == 'C' || profInt.dataStatus == 'U')) {
											if (updateProcessFlag) {
												profInt.dataStatus = 'U';
											} else {
												profInt.dataStatus = 'C';
											}
										}
										angular.extend(_selectedProfInt, profInt);
									}
								}		
							   
						});
					};
					
					ctrl.removeProfInt[intCat] = function() {		
						return $q(function(resolved, rejected){
							angular.forEach(ctrl.selectedProfInts[intCat], function(selectedProfInt, key) {
								angular.forEach(ctrl.product.profInts, function(profInt, index) {
									if (profInt.$$hashKey == selectedProfInt.$$hashKey) {
										if(!(profInt && profInt.dataStatus) || 'C' == profInt.dataStatus) {
											ctrl.product.profInts.splice(index, 1);
										} else {
											ctrl.product.profInts.dataStatus = 'D';
										}
									}
								});
							});
							resolved();
						});
					};
					
					ctrl.viewProfInt[intCat] = function(currRow) {		
						var params = {};
						// for show selected service on popup page
						var _selectedProfInt = currRow.entity;
						params.profInt = angular.copy(_selectedProfInt);
						// prodSubtypeExtProperty
						params.prodSubtypeExtProperty = ctrl.product.prodSubtypeExtProperty;
						// for update verify
						if (ctrl.productOldTmp && ctrl.productOldTmp['profInts' + intCat]) {
							var oldModel4SelectedRow;
							angular.forEach(ctrl.productOldTmp['profInts' + intCat], function(oldProfInt, index) {
								// profInt.ccy + ":" + profInt.intCat
								if (oldProfInt.ccy == params.profInt.ccy && oldProfInt.intCat == params.profInt.intCat) {
									oldModel4SelectedRow = oldProfInt;
								}
							});
							params.profIntOld = oldModel4SelectedRow;
						}
						modalService.openCustomDialogs({
						   'title': ' Interest Info',
						   'dialogsModule' : 'cda.profint.popupview',
						   'size' : [1100,500],
						   'params':params,
						   'btnCallback' : {
								'ok' : function(profCostOfFundInt) {						
								}
							}		
						});
					};
					
				})
			}
		}
		
		function initProfPastdue(initLayoutConfig, $scope, ctrl, updateProcessFlag) {
			//init profPastdue grid
			ctrl.profPastdueInnerGridOptions = gridService.createInnerGridOptions($scope, initLayoutConfig.formConfigs.profPastdue.tableConfigs.table, profPastdueRowSelectionChanged);
			ctrl.profPastdueInnerGridOptions.data = 'vm.product.profPastdues';
			ctrl.profPastdueInnerGridOptions.verifyData = 'vm.productOld.profPastdues';
			// if view page, delete table checkbox
			if (!ctrl.profPastdueInnerGridOptions.enableOperationRemoveSelected) {
				ctrl.profPastdueInnerGridOptions.enableRowHeaderSelection = false;
			}
			function profPastdueRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedProfPastdues = selectedRows;
			}
			
			ctrl.addProfPastdue = function(currRow) {
				return $q(function(resolved, rejected){
					// params
					var params = {};
					params.filterCcys = [];
					angular.forEach(ctrl.product.profPastdues, function(profPastdue, index) {
						params.filterCcys.push(profPastdue.ccy);
					});
					params.prodSubtypeExtProperty = ctrl.product.prodSubtypeExtProperty;
					params.isAdd = 'Y';
					modalService.openCustomDialogs({
					   'title': 'Past Due Info',
					   'dialogsModule' : 'cda.profpastdue.popupedit',
					   'size' : [1100,500],
					   'params': params,
					   'btnCallback' : {
						   'ok' : function(profPastdue) {							
							   angular.merge(currRow, profPastdue);
							   resolved();
							}
						}		
					});	
			   });
			};
			
			ctrl.editProfPastdue = function(currRow) {
				var params = {};
				// for show selected service on popup page
				var _selectedProfPastdue = currRow.entity;
				params.profPastdue = angular.copy(_selectedProfPastdue);
				params.filterCcys = [];
				angular.forEach(ctrl.product.profPastdues, function(profPastdue, index) {
					params.filterCcys.push(profPastdue.ccy);
				});
				params.isEdit = 'Y';
				params.prodSubtypeExtProperty = ctrl.product.prodSubtypeExtProperty;
				modalService.openCustomDialogs({
					   'title': 'Past Due Info',
					   'dialogsModule' : 'cda.profpastdue.popupedit',
					   'size' : [1100,500],
					   'params': params,
					   'btnCallback' : {
							'ok' : function(profPastdue) {							
								if (!ctrl.product.profPastdues) {								
									ctrl.product.profPastdues = [];
								}
								if (!(profPastdue.dataStatus == 'C' || profPastdue.dataStatus == 'U')) {
									if (updateProcessFlag) {
										profPastdue.dataStatus = 'U';
									} else {
										profPastdue.dataStatus = 'C';
									}
								}
								angular.extend(_selectedProfPastdue, profPastdue);
							}
						}		
					   
				});			
			};
			
			ctrl.viewProfPastdue = function(currRow) {		
				var params = {};
				// for show selected service on popup page
				var _selectedProfPastdue = currRow.entity;
				params.profPastdue = angular.copy(_selectedProfPastdue);
				//
				if (ctrl.productOld && ctrl.productOld.profPastdues) {
					var oldModel4SelectedRow;
					angular.forEach(ctrl.productOld.profPastdues, function(profPastdue, index) {
						if (profPastdue.ccy == params.profPastdue.ccy) {
							oldModel4SelectedRow = profPastdue;
						}
					});
					params.profPastdueOld = oldModel4SelectedRow;
				}
				params.prodSubtypeExtProperty = ctrl.product.prodSubtypeExtProperty;
				modalService.openCustomDialogs({
				   'title': 'Past Due Info',
				   'dialogsModule' : 'cda.profpastdue.popupview',
				   'size' : [1100,500],
				   'params':params,
				   'btnCallback' : {
						'ok' : function(profPastdue) {						
						}
					}		
				});
			};
			
		};
		
		
		function initProfFee(initLayoutConfig, $scope, ctrl, updateProcessFlag) {
			//init profFee grid
			ctrl.profFeeInnerGridOptions = gridService.createInnerGridOptions($scope, initLayoutConfig.formConfigs.profFee.tableConfigs.table, profFeeRowSelectionChanged);
			ctrl.profFeeInnerGridOptions.data = 'vm.product.profFees';
			ctrl.profFeeInnerGridOptions.verifyData = 'vm.productOld.profFees';
			// if view page, delete table checkbox
			if (!ctrl.profFeeInnerGridOptions.enableOperationRemoveSelected) {
				ctrl.profFeeInnerGridOptions.enableRowHeaderSelection = false;
			}
			function profFeeRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedProfFees = selectedRows;
			}
			
			ctrl.addProfFee = function(currRow) {
				return $q(function(resolved, rejected){
					//
					var bigestInEvtCcy = {};
//					angular.forEach(ctrl.product.profFees, function(profFee, index) {
//						var pre = bigestInEvtCcy[profFee.eventCode + ":" + profFee.ccy];
//						var now = profFee.feeCodeSeq;
//						if(pre && arithService.gt(now, pre)){
//							bigestInEvtCcy[profFee.eventCode + ":" + profFee.ccy] = now;
//						} else {
//							bigestInEvtCcy[profFee.eventCode + ":" + profFee.ccy] = now;
//						}
//					});
					angular.forEach(ctrl.product.profFees, function(profFee, index) {
						var pre = bigestInEvtCcy["big"];
						var now = profFee.feeCodeSeq;
						if(pre && arithService.gt(now, pre)){
							bigestInEvtCcy["big"] = now;
						} else {
							bigestInEvtCcy["big"] = now;
						}
					});
					// params
					var params = {};
					params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
					params.prodCode = ctrl.product.prodCode;
					params.bigestInEvtCcy = bigestInEvtCcy;
					params.profileType = '1P';
					params.profileId = ctrl.product.prodId;
					params.isAdd = 'Y';
					//
					params.filterPrimaryKeys = [];
					angular.forEach(ctrl.product.profFees, function(profFee, index) {
						params.filterPrimaryKeys.push(profFee.ccy + ":" + profFee.eventCode + ":" + profFee.feeCode);
					});
					modalService.openCustomDialogs({
					   'title': 'Fee Info',
					   'dialogsModule' : 'cda.proffee.popupedit',
					   'size' : [1100,500],
					   'params': params,
					   'btnCallback' : {
						   'ok' : function(profFee) {							
							   angular.merge(currRow, profFee);
							   resolved();
							}
						}		
					});	
			   });
			};
			
			ctrl.editProfFee = function(currRow) {
				var params = {};
				// for show selected service on popup page
				var _selectedProfFee = currRow.entity;
				params.profFee = angular.copy(_selectedProfFee);
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				params.prodCode = ctrl.product.prodCode;
				params.isEdit = 'Y';
				params.profileType = '1P';
				params.profileId = ctrl.product.prodId;
				//
				params.filterPrimaryKeys = [];
				angular.forEach(ctrl.product.profFees, function(profFee, index) {
					params.filterPrimaryKeys.push(profFee.ccy + ":" + profFee.eventCode + ":" + profFee.feeCode);
				});
				modalService.openCustomDialogs({
					   'title': 'Fee Info',
					   'dialogsModule' : 'cda.proffee.popupedit',
					   'size' : [1100,500],
					   'params': params,
					   'btnCallback' : {
							'ok' : function(profFee) {							
								if (!ctrl.product.profFees) {								
									ctrl.product.profFees = [];
								}
								if (!(profFee.dataStatus == 'C' || profFee.dataStatus == 'U')) {
									if (updateProcessFlag) {
										profFee.dataStatus = 'U';
									} else {
										profFee.dataStatus = 'C';
									}
								}
								angular.extend(_selectedProfFee, profFee);
							}
						}		
					   
				});			
			};
			
			ctrl.viewProfFee = function(currRow) {		
				var params = {};
				// for show selected service on popup page
				var _selectedProfFee = currRow.entity;
				params.profFee = angular.copy(_selectedProfFee);
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				//
				if (ctrl.productOld && ctrl.productOld.profFees) {
					var oldModel4SelectedRow;
					angular.forEach(ctrl.productOld.profFees, function(profFee, index) {
						// profFee.eventCode + ":" + profFee.ccy + ":" + profFee.feeCodeSeq
						if (profFee.eventCode == params.profFee.eventCode 
						&& profFee.ccy == params.profFee.ccy 
						&& profFee.feeCodeSeq == params.profFee.feeCodeSeq) {
							oldModel4SelectedRow = profFee;
						}
					});
					params.profFeeOld = oldModel4SelectedRow;
				}
				modalService.openCustomDialogs({
				   'title': 'Fee Info',
				   'dialogsModule' : 'cda.proffee.popupview',
				   'size' : [1100,500],
				   'params':params,
				   'btnCallback' : {
						'ok' : function(profFee) {						
						}
					}		
				});
			};
			
		};
		
		
		function initEventDoccfg(initLayoutConfig, $scope, ctrl, updateProcessFlag) {
			//init eventDoccfg grid
			ctrl.eventDoccfgInnerGridOptions = gridService.createInnerGridOptions($scope, initLayoutConfig.formConfigs.eventDoccfg.tableConfigs.table, eventDoccfgRowSelectionChanged);
			ctrl.eventDoccfgInnerGridOptions.data = 'vm.product.eventDoccfgs';
			ctrl.eventDoccfgInnerGridOptions.verifyData = 'vm.productOld.eventDoccfgs';
			// if view page, delete table checkbox
			if (!ctrl.eventDoccfgInnerGridOptions.enableOperationRemoveSelected) {
				ctrl.eventDoccfgInnerGridOptions.enableRowHeaderSelection = false;
			}
			function eventDoccfgRowSelectionChanged(eventRow, selectedRows) {
				ctrl.selectedEventDoccfgs = selectedRows;
			}
			
			ctrl.addEventDoccfg = function(currRow) {
				return $q(function(resolved, rejected){
					// params
					var params = {};
					params.filterEventCodes = [];
					angular.forEach(ctrl.product.eventDoccfgs, function(eventDoccfg, index) {
						params.filterEventCodes.push(eventDoccfg.eventCode + ":" + eventDoccfg.docType + ":" + eventDoccfg.localeCode);
					});
					params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
					params.isAdd = 'Y';
					modalService.openCustomDialogs({
					   'title': 'Document Info',
					   'dialogsModule' : 'cda.eventdoccfg.popupedit',
					   'params': params,
					   'btnCallback' : {
						   'ok' : function(eventDoccfg) {							
							   angular.merge(currRow, eventDoccfg);
							   resolved();
							}
						}		
					});
			   });
			};
			
			ctrl.editEventDoccfg = function(currRow) {
				var params = {};
				// for show selected service on popup page
				var _selectedEventDoccfg = currRow.entity;
				params.eventDoccfg = angular.copy(_selectedEventDoccfg);
				params.filterEventCodes = [];
				angular.forEach(ctrl.product.eventDoccfgs, function(eventDoccfg, index) {
					if (_selectedEventDoccfg.$$hashKey != eventDoccfg.$$hashKey) {
						params.filterEventCodes.push(eventDoccfg.eventCode + ":" + eventDoccfg.docType + ":" + eventDoccfg.localeCode);
					}
				});
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				params.isEdit = 'Y';
				modalService.openCustomDialogs({
					   'title': 'Document Info',
					   'dialogsModule' : 'cda.eventdoccfg.popupedit',
					   'params': params,
					   'btnCallback' : {
							'ok' : function(eventDoccfg) {							
								if (!ctrl.product.eventDoccfgs) {								
									ctrl.product.eventDoccfgs = [];
								}
								if (!(eventDoccfg.dataStatus == 'C' || eventDoccfg.dataStatus == 'U')) {
									if (updateProcessFlag) {
										eventDoccfg.dataStatus = 'U';
									} else {
										eventDoccfg.dataStatus = 'C';
									}
								}
								angular.extend(_selectedEventDoccfg, eventDoccfg);
							}
						}		
					   
				});			
			};
			
			ctrl.viewEventDoccfg = function(currRow) {		
				var params = {};
				// for show selected service on popup page
				var _selectedEventDoccfg = currRow.entity;
				params.eventDoccfg = angular.copy(_selectedEventDoccfg);
				params.prodType = ctrl.product.prodSubtypeExtProperty.prodType;
				//
				if (ctrl.productOld && ctrl.productOld.eventDoccfgs) {
					var oldModel4SelectedRow;
					angular.forEach(ctrl.productOld.eventDoccfgs, function(eventDoccfg, index) {
						if (eventDoccfg.primaryKey == params.eventDoccfg.primaryKey) {
							oldModel4SelectedRow = eventDoccfg;
						}
					});
					params.eventDoccfgOld = oldModel4SelectedRow;
				}
				modalService.openCustomDialogs({
				   'title': 'Document Info',
				   'dialogsModule' : 'cda.eventdoccfg.popupview',
				   'params':params,
				   'btnCallback' : {
						'ok' : function(eventDoccfg) {						
						}
					}		
				});
			};
			
		};
		
		
		function initMultiProfLimitFaci(initLayoutConfig, $scope, ctrl, updateProcessFlag) {
			if(ctrl.facilityCatOptions){
				ctrl.profLimitFaciCats = angular.copy(ctrl.facilityCatOptions);// for page ng-repeat
				ctrl.profLimitFaciMultiInnerGridOptions = {};
				ctrl.selectedProfLimitFacis = {};
				ctrl.addProfLimitFaci = {};
				ctrl.editProfLimitFaci = {};
				ctrl.viewProfLimitFaci = {};
				ctrl.removeProfLimitFaci = {};
				angular.forEach(ctrl.facilityCatOptions, function(facilityCatOption) {
					var facilityCat = facilityCatOption.value;
					//init profCostOfFundLimitFaci grid
					var profLimitFaciLayoutName = 'profLimitFaci' + facilityCat;
					var profLimitFaciRowSelectionChanged = {};
					profLimitFaciRowSelectionChanged[facilityCat] = function(eventRow, selectedRows) {
						ctrl.selectedProfLimitFacis[facilityCat] = selectedRows;
					}
					ctrl.profLimitFaciMultiInnerGridOptions[facilityCat] = gridService.createInnerGridOptions($scope, initLayoutConfig.formConfigs[profLimitFaciLayoutName].tableConfigs.table, profLimitFaciRowSelectionChanged[facilityCat]);
					ctrl.profLimitFaciMultiInnerGridOptions[facilityCat].data = 'vm.productTmp.profLimitFacis' + facilityCat;
					ctrl.profLimitFaciMultiInnerGridOptions[facilityCat].verifyData = 'vm.productOldTmp.profLimitFacis' + facilityCat;
					// if view page, delete table checkbox
					if (!ctrl.profLimitFaciMultiInnerGridOptions[facilityCat].enableOperationRemoveSelected) {
						ctrl.profLimitFaciMultiInnerGridOptions[facilityCat].enableRowHeaderSelection = false;
					}
					
					ctrl.addProfLimitFaci[facilityCat] = function(currRow) {
						return $q(function(resolved, rejected){
							var params = {};
							var bigestSeqInCat = {};
							angular.forEach(ctrl.productTmp['profLimitFacis' + facilityCat], function(profLimitFaci, index) {
								var pre = bigestSeqInCat[profLimitFaci.facilityCat];
								var now = profLimitFaci.facilitySeq;
								if(pre && arithService.gt(now, pre)){
									bigestSeqInCat[profLimitFaci.facilityCat] = now;
								} else {
									bigestSeqInCat[profLimitFaci.facilityCat] = now;
								}
							});
							params.bigestSeqInCat = bigestSeqInCat;
							params.profLimitFaci = {};
							params.profLimitFaci.facilityCat = facilityCat;
							params.isAdd = 'Y';
							modalService.openCustomDialogs({
							   'title': 'Prof LimitFaci Edit',
							   'dialogsModule' : 'cda.proflimitfaci.popupedit',
							   'params': params,
							   'btnCallback' : {
								   'ok' : function(profLimitFaci) {	
									   // only add ctrl.product.profLimitFaciTmpsx
									   angular.merge(currRow, profLimitFaci);
									   // also need add in ctrl.product.profLimitFacis for submit service
									   if (!ctrl.product.profLimitFacis) ctrl.product.profLimitFacis = [];
									   ctrl.product.profLimitFacis.push(currRow);
									   resolved();
									}
								}		
							});
					   });
					};
					
					ctrl.editProfLimitFaci[facilityCat] = function(currRow) {
						var params = {};
						// for show selected service on popup page
						var _selectedProfLimitFaci = currRow.entity;
						params.profLimitFaci = angular.copy(_selectedProfLimitFaci);
						params.isEdit = 'Y';
						modalService.openCustomDialogs({
							   'title': 'Prof LimitFaci Edit',
							   'dialogsModule' : 'cda.proflimitfaci.popupedit',
							   'params': params,
							   'btnCallback' : {
									'ok' : function(profLimitFaci) {							
										if (!(profLimitFaci.dataStatus == 'C' || profLimitFaci.dataStatus == 'U')) {
											if (updateProcessFlag) {
												profLimitFaci.dataStatus = 'U';
											} else {
												profLimitFaci.dataStatus = 'C';
											}
										}
										angular.extend(_selectedProfLimitFaci, profLimitFaci);
									}
								}		
						});	
					};
					
					ctrl.removeProfLimitFaci[facilityCat] = function() {		
						return $q(function(resolved, rejected){
							// remove from ctrl.product.profLimitFacis
							angular.forEach(ctrl.selectedProfLimitFacis[facilityCat], function(selectedProfLimitFaci, key) {
								angular.forEach(ctrl.product.profLimitFacis, function(profLimitFaci, index) {
									if (profLimitFaci.$$hashKey == selectedProfLimitFaci.$$hashKey) {
										if(!(profLimitFaci && profLimitFaci.dataStatus) || 'C' == profLimitFaci.dataStatus) {
											ctrl.product.profLimitFacis.splice(index, 1);
										} else {
											ctrl.product.profLimitFacis.dataStatus = 'D';
										}
									}
								});
							});
							// remove from ctrl.productTmp.profLimitFacis by framework
							resolved();
						});
					};
					
					ctrl.viewProfLimitFaci[facilityCat] = function(currRow) {
						var params = {};
						// for show selected service on popup page
						var _selectedProfLimitFaci = currRow.entity;
						params.profLimitFaci = angular.copy(_selectedProfLimitFaci);
						if (ctrl.productOldTmp && ctrl.productOldTmp['profLimitFacis' + facilityCat]) {
							var oldModel4SelectedRow;
							angular.forEach(ctrl.productOldTmp['profLimitFacis' + facilityCat], function(oldProfLimitFaci, index) {
								if (oldProfLimitFaci.profFacilityId == params.profLimitFaci.profFacilityId) {
									oldModel4SelectedRow = oldProfLimitFaci;
								}
							});
							params.profLimitFaciOld = oldModel4SelectedRow;
						}
						modalService.openCustomDialogs({
						   'title': 'Prof LimitFaci View',
						   'dialogsModule' : 'cda.proflimitfaci.popupview',
						   'params':params,
						   'btnCallback' : {
								'ok' : function(profLimitFaci) {						
								}
							}		
						});
					};
				});
			}
		}
		
		
		// if no this tab, data need clear
		function clearDirtyData (ctrl) {
			if (!(ctrl.product.dataStatus && ctrl.product.prodSubtypeExtProperty.upBilling == 'Y')) {
				delete ctrl.product.profBilling;
			}
			
			angular.forEach(ctrl.intCatOptions, function(intCatOption) {
				var intCat = intCatOption.value;
				if (!(ctrl.product.dataStatus && ctrl.product.interestCatShowFlag[intCat] == 'Y')) {
					if (ctrl.product.profInts && ctrl.product.profInts.length > 0) {
						for (var j = ctrl.product.profInts.length - 1; j >= 0; j--) {
							if (ctrl.product.profInts[j].intCat == intCat) {
								// delete
								ctrl.product.profInts.splice(j, 1);
							}
						}
					}
				}
			});
			
			angular.forEach(ctrl.facilityCatOptions, function(facilityCatOption) {
				var facilityCat = facilityCatOption.value;
				if (!(ctrl.product.dataStatus && ctrl.product.facilityCatShowFlag[facilityCat] == 'Y')) {
					if (ctrl.product.profLimitFacis && ctrl.product.profLimitFacis.length > 0) {
						for (var j = ctrl.product.profLimitFacis.length - 1; j >= 0; j--) {
							if (ctrl.product.profLimitFacis[j].facilityCat == facilityCat) {
								// delete
								ctrl.product.profLimitFacis.splice(j, 1);
							}
						}
					}
				}
			});
		}
		
		function initListOptions($scope, ctrl) {
			var defer = $q.defer();
			ajaxService.getProdSubtypeOptions().then(function(response) {
				ctrl.prodSubtypeOptions = response.data;
				defer.resolve();
			});
			return defer.promise;
		}	
		
		return {
			initGeneral : initGeneral,
			initLayoutConfigAndModel : initLayoutConfigAndModel,
			initProfAcct : initProfAcct,
			initProfPastdue : initProfPastdue,
			initProfFee : initProfFee,
			initEventDoccfg : initEventDoccfg,
			clearDirtyData : clearDirtyData,
			initListOptions : initListOptions
		};
	}
})(angular);